#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <unistd.h>
#include <iostream>
#include <thread>
#include <string.h>

#include "client.h"
#include "clientMessage.h"
#include "protocol.h"

using namespace std;

bool Client::m_running = true;

Client::Client(string addr, int port) 
    : m_addr(addr)
    , m_port(port)
{

}

Client::~Client()
{

}

void Client::run()
{

    //定义 sockfd
    m_sockfd = socket(AF_INET, SOCK_STREAM, 0);

    //定义sockaddr_in
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(m_port);                      // 服务器端口
    servaddr.sin_addr.s_addr = inet_addr(m_addr.c_str());   // 服务器 ip

    // 连接服务器，成功返回0，错误返回-1
    if (connect(m_sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("connect failed.");
        exit(1);
    }
    cout << "连接服务器成功\n";

    // 创建发送线程和接收线程
    thread recv_t(RecvMsg, m_sockfd);
    recv_t.detach();
    
    return;
}

void Client::RecvMsg(int conn)
{
    // 接收缓冲区
    char buffer[1000];
    // 不断接收数据
    while(m_running)
    {
        memset(buffer, 0, sizeof(buffer));
        int len = recv(conn, buffer, sizeof(buffer),0);
        cout << "收到服务器发来的信息：" << buffer << endl;
    }
}

bool Client::handle(const LoginMsg *pMsg)
{
    cout << "user: " << pMsg->user << ", passwd: " << pMsg->passwd << endl;
    CommProtocol t;
    memset(&t, 0, sizeof(t));
    t.header = 0x17;
    t.type = DT_LOGIN;
    memcpy(t.data.login_info.id, "17", 2);
    memcpy(t.data.login_info.user, pMsg->user.c_str(), pMsg->user.size());
    memcpy(t.data.login_info.passwd, pMsg->passwd.c_str(), pMsg->passwd.size());
    
    int ret = send(m_sockfd, (char*)&t, sizeof(t), 0);

    ClientResultMessgae rmsg;
    rmsg.type = RT_LOGIN;
    rmsg.result = true;
    rmsg.post();
    return true;
}

bool Client::handle(const RegisterMsg *pMsg)
{
    cout << "user: " << pMsg->user << ", passwd: " << pMsg->passwd << endl;
    CommProtocol t;
    memset(&t, 0, sizeof(t));
    t.header = 0x17;
    t.type = DT_REGISTER;
    memcpy(t.data.reg_info.id, "17", 2);
    memcpy(t.data.reg_info.user, pMsg->user.c_str(), pMsg->user.size());
    memcpy(t.data.reg_info.passwd, pMsg->passwd.c_str(), pMsg->passwd.size());
    
    int ret = send(m_sockfd, (char*)&t, sizeof(t), 0);

    ClientResultMessgae rmsg;
    rmsg.type = RT_REGISTER;
    rmsg.result = true;
    rmsg.post();
    return true;
}

bool Client::handle(const CmdMsg *pMsg)
{
    cout << pMsg->cmd << " client close.\n";
    if(pMsg->cmd == CT_EXIT)
        close(m_sockfd);
    return true;
}